package com.xdf.whiteaccount.service.impl;

import com.xdf.whiteaccount.dao.CallMapper;
import com.xdf.whiteaccount.dao.JrkbillAdjustMapper;
import com.xdf.whiteaccount.entity.JrkbillAdjust;
import com.xdf.whiteaccount.enums.ModifyTypeEnum;
import com.xdf.whiteaccount.service.JrkbillAdjustService;
import com.xdf.whiteaccount.service.base.BaseService;
import com.xdf.whiteaccount.utils.CalculateUtil;
import com.xdf.whiteaccount.vo.PlanDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * @Description : com.xdf.whiteaccount.service.impl(业务层实现类,该类为生成器自动生成).
 * @Author : 张柯
 * @Date : 2021-06-04 17:17:21
 */
@Service
public class JrkbillAdjustServiceImpl extends BaseService implements JrkbillAdjustService {
    @Autowired
    private JrkbillAdjustMapper dao;
    @Autowired
    private CallMapper callMapper;

    /**
     * @Describe 新增方法
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(JrkbillAdjust record) throws Exception {
        return dao.insert(record);
    }

    /**
     * @Describe 选择新增
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSelective(JrkbillAdjust record) throws Exception {
        return dao.insertSelective(record);
    }

    /**
     * @Describe 批量新增
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiInsert(List<JrkbillAdjust> list) throws Exception {
        return dao.multiInsert(list);
    }

    /**
     * @Describe 修改
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(JrkbillAdjust record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * @Describe 选择修改
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKeySelective(JrkbillAdjust record) throws Exception {
        return dao.updateByPrimaryKeySelective(record);
    }

    /**
     * @Describe 修改
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(JrkbillAdjust record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * @Describe 批量修改
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiUpdate(List<JrkbillAdjust> list) throws Exception {
        return dao.multiUpdate(list);
    }

    /**
     * @Describe 根据主键查询
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    public JrkbillAdjust selectByPrimaryKey(Integer id) throws Exception {
        return dao.selectByPrimaryKey(id);
    }

    /**
     * @Describe 根据主键删除
     * 在 2021年8月29日 16:22:42 追加了移库功能，该功能会产生两笔关联的数据
     * 删除其中一笔将连带删除另外一笔
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByPrimaryKey(Integer id) throws Exception {
        Assert.notNull(id,"未传入主键，无法删除！");
        JrkbillAdjust jrkbillAdjust = Optional.ofNullable(selectByPrimaryKey(id)).orElse(new JrkbillAdjust());
        String opbatch = Optional.ofNullable(jrkbillAdjust.getOpbatch()).orElse("");
        int ret = 0;
        // 如果被删除的目标行存在 opbatch，则按照该字段的值删除多笔数据
        if( opbatch.length()>0 )
            ret = deleteByOpbatch(opbatch);
        else
            ret = dao.deleteByPrimaryKey(id);
        return ret;
    }

    /**
     * @Describe 根据Entity查询
     * @author 张柯
     * @Date 2021-06-04 17:17:21
     */
    @Override
    public List<JrkbillAdjust> listQuery(JrkbillAdjust record) throws Exception {
        return dao.selectByParam(record);
    }

    /**
     * 自动调整库存
     *
     * @param record
     * @return
     * @throws Exception
     */
    @Override
    public int storeModifyByPlanId(JrkbillAdjust record) throws Exception {
        PlanDetailVO vo = callMapper.getPlanDtl(record.getPlanId());
        Assert.notNull(vo, "计划单不存在！");
        Integer ps = (int) CalculateUtil.sub(record.getPairs(),
                Optional.ofNullable(vo).map(PlanDetailVO::getRemainPairs).orElse(new BigDecimal(0)).doubleValue());
        BigDecimal qty = CalculateUtil.sub(record.getQty(), vo.getRemainKilo());
        if (ps == 0 && qty.doubleValue() == 0D) return 0;
        JrkbillAdjust item = JrkbillAdjust.builder()
                .billType(ModifyTypeEnum.CHECKOUT.getName())
                .cancelTime(new Date())
                .cancelUserId(getLoginUserId())
                .isPush(false)
                .upload(0)
                .jrkbillDate(new Date())
                .pairs(ps)
                .qty(qty)
                .planId(record.getPlanId())
                .build();
        return dao.insertSelective(item);
    }

    @Transactional
    @Override
    public int migrateStock(Long ido, Long idt, Integer pairs, BigDecimal qty) {
        // 检测传入参数的合法性
        if( ido == null || ido <= 0 ) throw new RuntimeException("移库中传入了空的主键！");
        if( idt == null || idt <= 0 ) throw new RuntimeException("移库中传入了空的主键！");

        int diff = BigDecimal.valueOf(0).compareTo(qty);
        if( Integer.valueOf(0).equals(pairs) && diff == 0 ) throw new RuntimeException("匹数和公斤不可同时为0！");

        Date billDate = new Date();
        String opbatch = getUUID();
        // 写入源头
        JrkbillAdjust jrkbillAdjust1 = new JrkbillAdjust();
        jrkbillAdjust1.setPlanId(ido);
        jrkbillAdjust1.setJrkbillDate(billDate);
        jrkbillAdjust1.setPairs(pairs * -1); // 源是移出数量，所以要 * -1
        jrkbillAdjust1.setQty(qty.multiply(BigDecimal.valueOf(-1)));
        jrkbillAdjust1.setBillType("移库");// getLoginUserId
        jrkbillAdjust1.setCreateUserId(getLoginUserId());
        jrkbillAdjust1.setOpbatch(opbatch);

        // 写入目标 - 数据要取反
        JrkbillAdjust jrkbillAdjust2 = new JrkbillAdjust();
        jrkbillAdjust2.setPlanId(idt);
        jrkbillAdjust2.setJrkbillDate(billDate);
        jrkbillAdjust2.setPairs(pairs);
        jrkbillAdjust2.setQty(qty);
        jrkbillAdjust2.setBillType("移库");// getLoginUserId
        jrkbillAdjust2.setCreateUserId(getLoginUserId());
        jrkbillAdjust2.setOpbatch(opbatch);

        dao.insertSelective(jrkbillAdjust1);
        dao.insertSelective(jrkbillAdjust2);
        return 1;
    }

    @Override
    public int deleteByOpbatch(String opbatch) {
        return dao.deleteByOpbatch(opbatch);
    }

    private String getUUID(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
}